<?php
// +----------------------------------------------------------------------
// | 中犇单商户
// +----------------------------------------------------------------------
// | Copyright (c) 2019-2021 中犇科技 All rights reserved.
// +----------------------------------------------------------------------

namespace app\operation\model;
use app\user\model\User;
use think\Model as ThinkModel;

/**
 * 站内信
 * Class SystemMessage
 * @package app\user\model
 * @author 刘明美 [ liumingmei@zhongbenjituan.com ]
 * @since 2019/4/9 16:24
 */
class SystemMessage extends ThinkModel
{

    //设置表名
    protected $table = '__OPERATION_SYSTEM_MESSAGE__';
    // 自动写入时间戳
    protected $autoWriteTimestamp = true;
    
    protected static $create_times = [];

    public static $msgtype = [
        1 => '系统消息',
        2 => '订单信息',
        3 => '其他消息', 
    ];
    
    /**
     * 注册写入事件监听器，可在create之后自动进行推送
     * 在操作中，只需要 用 SystemMessage::create([...params]) 写入即可，无需关注推送逻辑
     * 如不需要推送，可在params参数中添加 is_system=0
     * 如不能推送，请检查插件中个推是否开启
     * @date 2021年11月8日11:10:48
     * @author 晓风<215628355@qq.com>
     */
    protected static function init()
    {
        $open =  module_config("operation.message_send");   
        if(!$open){
            return true;
        }
        $that = new static();        
        self::afterInsert(function ($data) use($that){
            //构建数据
            $is_system= $data["is_system"] ?? 1 ;
            if(!$is_system){ //写入参数不允许推送
                return true;
            }
            $data["custom"] = $data["custom"] ?? "";
            $data["to_user_id"] =  $data["to_user_id"] ??  "";
            $data["action"] = $data["action"] ?? 0 ;
            $data["msg_type"] = $data["msg_type"] ?? 0 ;
            
            if(!isset($data["id"])){
                return true;
            }
            if(!isset($data["title"])){
                return true;
            }
            if(!isset($data["content"])){
                $data["content"] = $data["title"];
            }         
            //执行推送
            try{                
               //执行异步推送，PHP 需可全局执行,并需要放开禁用函数 popen/pclose 方法支持 
               if(function_exists('popen') && function_exists('pclose')){
                   \util\AsyncCommand::think('sendMessage', [$data['id']]);
               }else{
                   $that->sendMsg($data);  //同步推送
               }
            }catch(\Exception $e){
                
            }catch(\Error $e){
                
            }
            return true;
        });
    }    

    /**
     * 推送一个站内信
     * 默认是个推
     * @param array|object $message  消息体-基于get方法查询返回的数据对象或者手动创建的数组
     * @param string $to_user_id 接收人列表，默认根据消息体内的$to_user_id，如有此参数，则依据此参数，（空值全体推送，多个ID逗号隔开是群推，单个ID是单推）
     * @return boolean|string
     * @author 晓风<215628355@qq.com>
     */
    public function sendMsg($message, $to_user_id = null)
    {    
        $open =  module_config("operation.message_send");   
        if(!$open){
            return true;
        }
        
        $extra = $message["custom"];
        if (is_array($json = json_decode($message["custom"], true))) {
            $extra = $json;
        }


        $title = $message["title"];
        $content = $message["content"];
        $custom = json_encode([
            "id" => $message["id"],
            "action" => $message["action"],
            "msg_type" => $message["msg_type"],
            "extra" => $extra
        ]);
        $logo = "";
        $logoUrl = "";
        $sound = "default";
        $badge = -1;

        if (null == $to_user_id) {
            $to_user_id = $message['to_user_id'];
        }
        $to_user_id = explode(",", $to_user_id);
        if (count($to_user_id) <= 1) {
            $to_user_id = $to_user_id[0];
        }
        $type = is_array($to_user_id) ? 2 : ($to_user_id ? 1 : 3);

        switch ($type) {
            case 1:
                //单推
                $client_id = \think\Db::name('user')->where('id', $to_user_id)->value('client_id');
             
                if (!$client_id) {
                    $this->error = '获取指定用户的client_id失败，无法发送';
                    return false;
                }
                $res = addons_action('Getui/Getui/pushMessageToSingle', [$title, $content, $client_id, $custom, $logo, $logoUrl, $sound, $badge]);       
                //addons_action('Getui/Transmission/pushMessageToSingle', [$title, $content, $client_id,$custom]); //纯透传-若IOS打开收不到消息
                break;
            case 2:
                $client_id = \think\Db::name('user')->where('id', 'in', $to_user_id)->column('client_id');
                if (!$client_id) {
                    $this->error = '获取指定用户的client_id失败，无法发送';
                    return false;
                }
                //多推
                $res = addons_action('Getui/Getui/pushMessageToList', [$title, $content, $client_id, $custom, $logo, $logoUrl, $sound, $badge]);
                //addons_action('Getui/Transmission/pushMessageToList', [$title, $content, $client_id,$custom]); //纯透传-若IOS打开收不到消息
                break;
            case 3:
                //群推
                $res = addons_action('Getui/Getui/pushMessageToApp', [$title, $content, $custom, $logo, $logoUrl, $sound, $badge]);
                //addons_action('Getui/Transmission/pushMessageToApp', [$title, $content, $custom]); //纯透传-若IOS打开收不到消息
                break;
        }
        \think\facade\Log::info("send_message:" . json_encode($res));
        if ($res['code'] == '0') {
            return true;
        }
        $this->error = $res['msg'];
        return false;
    }

    /**
     * 获取会员创建时间
     * @author 晓风<215628355@qq.com>
     * @param int $user_id 会员ID
     * @return int
     */
    public static function getUserCreateTime($user_id){
        if(isset(self::$create_times[$user_id])){
            return self::$create_times[$user_id];
        }
        $create_time = User::where('id', $user_id)->value('create_time');
        self::$create_times[$user_id] = $create_time ?: 0;
        return $create_time ?: 0;
    }

    /**
     * 获取我的系统消息
     * @param int $userId 会员ID
     * @return object
     * @author 晓风<215628355@qq.com>
     */
    public static function getList($userId, $msgtype = 0)
    {
        if ($msgtype > 0) {
            $map[] = ['operation_system_message.msg_type', '=', $msgtype];
        }
       
       return self::view("operation_system_message", true)
            ->view("operation_system_message_read", "aid as readid", 'operation_system_message_read.sys_msg_id = operation_system_message.id and operation_system_message_read.user_id=:user_id', "left")
            ->bind(['user_id' => $userId])
            ->where('operation_system_message.create_time', ">", self::getUserCreateTime($userId))
            ->where(function ($query) use ($userId) {
                  $query->where("operation_system_message.to_user_id", $userId)
                    ->whereOr("operation_system_message.to_user_id", 0)
                    ->whereOr("operation_system_message.to_user_id", '')
                    ->whereOr("operation_system_message.to_user_id", null);
            })
            ->where($map)
            ->where("operation_system_message_read.aid IS NULL OR operation_system_message_read.status = 1")
            ->order("operation_system_message.create_time desc")
            ->paginate()->each(function ($item) use ($userId) {
                if (!$item['readid']) {
                    //更正消息已读user_id
                    SystemMessageRead::setread($userId, $item['id']);
                }
                $item['is_read'] = $item['readid'] ? 1 : 0;
                $item['thumb'] =  $item['thumb'] ? get_thumb($item['thumb']) : "";
                $item['from'] = '来自：系统消息';
                return $item;
            });      
             
    }


    /**
     * 获取我的系统消息
     * @param int $user_id 会员ID
     * @return object
     * @author 晓风<215628355@qq.com>
     */
    public static function getMessageCount($user_id, $msgtype = 0)
    {
        $map = [];
        if ($msgtype > 0) {
            $map['operation_system_message.msg_type'] = $msgtype;
        }
        //查询用户注册时间    
        return self::view("operation_system_message", true)
            ->view("operation_system_message_read", "aid as readid", 'operation_system_message_read.sys_msg_id = operation_system_message.id and operation_system_message_read.user_id=:user_id', "left")
            ->bind(['user_id' => $user_id])
            ->where('operation_system_message.create_time', ">", self::getUserCreateTime($user_id))
            ->where(function ($query) use ($user_id) {
                  $query->where("operation_system_message.to_user_id", $user_id)
                    ->whereOr("operation_system_message.to_user_id", 0)
                    ->whereOr("operation_system_message.to_user_id", '')
                    ->whereOr("operation_system_message.to_user_id", null);
            })
            ->where($map)
            ->where("operation_system_message_read.aid IS NULL OR operation_system_message_read.status = 1")
            ->order("operation_system_message.create_time desc")
            ->count();


    }
    
   /**
     * 获取我的未读系统消息数量
     * @param int $user_id 会员ID
     * @return object
     * @author 晓风<215628355@qq.com>
     */
    public static function getNoreadCount($user_id, $msgtype = 0)
    {
       
        $map = [];
        if ($msgtype > 0) {
            $map['operation_system_message.msg_type'] = $msgtype;
        }
    
        return self::view("operation_system_message", true)
            ->view("operation_system_message_read", "aid as readid", 'operation_system_message_read.sys_msg_id = operation_system_message.id and operation_system_message_read.user_id=:user_id', "left")
            ->bind(['user_id' => $user_id])
            ->where('operation_system_message.create_time', ">", self::getUserCreateTime($user_id))
            ->where(function ($query) use ($user_id) {
                $query->where("operation_system_message.to_user_id", $user_id)
                    ->whereOr("operation_system_message.to_user_id", 0)
                    ->whereOr("operation_system_message.to_user_id", "")
                    ->whereOr("operation_system_message.to_user_id", null);
            })
            ->where($map)
            ->where("operation_system_message_read.aid IS NULL")           
            ->count();
    }

    /**
     * 获取我的系统消息最新一条和未读数量
     * @param int $userId 会员ID
     * @return object
     * @author 晓风<215628355@qq.com>
     */
    public static function getMessage($userId, $msgtype = 0)
    {             
        $map = [];
        if ($msgtype > 0) {
            $map['operation_system_message.msg_type'] = $msgtype;
        }
         
        $fromA =  self::view("operation_system_message", true)
            ->view("operation_system_message_read", "aid as readid", 'operation_system_message_read.sys_msg_id = operation_system_message.id and operation_system_message_read.user_id=:user_id', "left")
             ->bind(['user_id' => $userId])
             ->where('operation_system_message.create_time', ">", self::getUserCreateTime($userId))
             ->where(function ($query) use ($userId) {
                $query->where("operation_system_message.to_user_id", $userId)
                    ->whereOr("operation_system_message.to_user_id", 0)
                    ->whereOr("operation_system_message.to_user_id", "")
                    ->whereOr("operation_system_message.to_user_id", null);
             })
            ->where($map);   
        $fromB = clone $fromA;//克隆一个对象，用作统计查询
        $res = $fromA->order('operation_system_message.id desc')->find();  
        if(!$res){
            return false;
        }
        $res['num'] = $fromB->where("operation_system_message_read.aid IS NULL")->count(); 
        return $res;
    }


    /**
    * 发送消息辅助类,建议直接create
    * @param  $to_user_id 指定接收人ID
    * @param  $title 消息标题
    * @param  $content 消息内容
    * @param  $msg_type 消息分类
    * @param  $click_type  透传点击事件对象名称（如 order 表示订单）  
    * @param  $click_id 透传点击事件对象ID（如订单号）
    * @param  $order_sn 订单号，仅限订单消息类型
    * @param  $thumb 图片，仅限订单消息类型
    * @param  $link 小程序跳转链接
    * @author undefined<undefined> 原作者未知
    * @editer 晓风<215628355@qq.com>  2021年11月8日11:29:41 调整参数
    */
    public static function send_msg($to_user_id, $title, $content, $msg_type, $click_type = "", $click_id = "", $order_sn = "",$thumb = 0, $link = '')
    {
        $message = self::create([
            'to_user_id' => $to_user_id,
            'title' => $title,
            'content' => $content,
            'is_read' => 0,
            'create_time' => time(),
            'msg_type' => $msg_type,     
            "custom"=> $click_type ? json_encode(['type'=> $click_type,'id'=>    $click_id]) : '',
            'order_sn' => $order_sn,
            'thumb' => $thumb,
            'link' => $link,           
        ]);
        if ($message) {
            return true;
        } else {
            return false;
        }
    }
}
